Skip to content

refactor: migrate multichain account components to DS#30249

Open
gantunesr wants to merge 5 commits into
mainfrom
gar/refactor/mul-1693
Open

refactor: migrate multichain account components to DS#30249
gantunesr wants to merge 5 commits into
mainfrom
gar/refactor/mul-1693

Conversation

@gantunesr
Copy link
Copy Markdown
Member

@gantunesr gantunesr commented May 15, 2026

Description

Migrates the MultichainAccounts temporary component internals away from deprecated component-library imports and onto @metamask/design-system-react-native equivalents.

This updates account rows, external account rows, account selector list pieces, address rows, checkboxes, search fields, text, icons, sensitive text, and avatar usage. It also adds a small avatar variant compatibility helper so legacy persisted selector values such as Maskicon, JazzIcon, and Blockies continue to map to the DS AvatarAccountVariant API.

Changelog

CHANGELOG entry: null

Related issues

Fixes: https://consensyssoftware.atlassian.net/browse/MUL-1693

Manual testing steps

Feature: Multichain account component DS migration

  Scenario: account selector and address rows preserve existing behavior
    Given a wallet with multichain account groups and network addresses

    When the account selector and multichain address list are opened
    Then account rows, external account rows, network avatars, checkboxes, copy actions, and search fields render and behave as before

Screenshots/Recordings

Screen.Recording.2026-05-15.at.4.13.43.PM.mov

Pre-merge author checklist

Performance checks (if applicable)

  • I've tested on Android
    • Ideally on a mid-range device; emulator is acceptable
  • I've tested with a power user scenario
    • Use these power-user SRPs to import wallets with many accounts and tokens
  • I've instrumented key operations with Sentry traces for production performance metrics

For performance guidelines and tooling, see the Performance Guide.

Pre-merge reviewer checklist

  • I've manually tested the PR (e.g. pull and build branch, run the app, test code being changed).
  • I confirm that this PR addresses all acceptance criteria described in the ticket it closes and includes the necessary testing evidence such as recordings and or screenshots.

Note

Medium Risk
Medium risk because it replaces core account-selector UI primitives (avatars, text, search, checkbox, toast wiring) with Design System components, which could cause subtle rendering/interaction regressions across account selection flows.

Overview
Migrates the temporary MultichainAccounts UI components (AccountCell, selector list cells/headers, external account rows, address rows, and address rows list) from deprecated component-library primitives to @metamask/design-system-react-native equivalents (text, icons, sensitive text, avatars, search, checkbox).

Introduces avatarAccountVariant compatibility helpers to map legacy persisted avatar type strings (Maskicon/JazzIcon/Blockies) to DS AvatarAccountVariant, and updates tests to assert DS components/testIDs (including new checkbox icon and network avatar test IDs) and to use timer-safe act/fake-timer handling for copy/toast feedback.

Reviewed by Cursor Bugbot for commit 9a035d1. Bugbot is set up for automated code reviews on this repo. Configure here.

@github-actions github-actions Bot added the pr-not-ready-for-e2e Skip E2E and block merging. Remove this label once the PR is ready to run the E2E tests. label May 15, 2026
@metamaskbotv2 metamaskbotv2 Bot added the team-accounts-framework Accounts team label May 15, 2026
@gantunesr gantunesr marked this pull request as ready for review May 15, 2026 20:01
@gantunesr gantunesr requested a review from a team as a code owner May 15, 2026 20:01
@gantunesr gantunesr removed the pr-not-ready-for-e2e Skip E2E and block merging. Remove this label once the PR is ready to run the E2E tests. label May 15, 2026
@gantunesr gantunesr added the no-changelog no-changelog Indicates no external facing user changes, therefore no changelog documentation needed label May 20, 2026
closeButtonOptions: {
variant: ButtonIconVariant.Icon,
iconName: ToastIconName.Close,
variant: 'Icon',
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see some ButtonIconVariant in the DS package, but none of them matches 'Icon', should we use ButtonIconVariant.Default instead?

Copy link
Copy Markdown
Member Author

@gantunesr gantunesr May 20, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think so because the interface expects the value Icon and ButtonIconVariant.Default is set to default. @MetaMask/design-system can you double check this?

@ccharly lets wait for the team to chime in and lets not block the PR

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(I'll keep this unresolved for visibility)

(typeof AvatarAccountType)[keyof typeof AvatarAccountType];

export const getAvatarAccountVariant = (
avatarAccountType: AccountAvatarVariant,
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this also use LegacyAvatarAccountType?

Suggested change
avatarAccountType: AccountAvatarVariant,
avatarAccountType: AccountAvatarVariant | LegacyAvatarAccountType,

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

AccountAvatarVariant already takes into account the legacy type:

export type AccountAvatarVariant =
  | AvatarAccountVariant
  | LegacyAvatarAccountType;

@github-actions
Copy link
Copy Markdown
Contributor

🔍 Smart E2E Test Selection

  • Selected E2E tags: SmokeAccounts, SmokeConfirmations, SmokeNetworkExpansion, SmokeNetworkAbstractions, SmokeSwap, SmokeWalletPlatform, SmokeIdentity
  • Selected Performance tags: @PerformanceAccountList
  • Risk Level: medium
  • AI Confidence: 78%
click to see 🤖 AI reasoning details

E2E Test Selection:
The PR migrates MultichainAccounts component library components from legacy internal design system components to the new @metamask/design-system-react-native package. Key changes include:

  1. AccountCell.tsx: Migrated AvatarAccount, Text, SensitiveText, Icon, Avatar to new DS equivalents. Props renamed (accountAddressaddress, typevariant, imageSourcesrc). TextVariant/TextColor enum values updated.

  2. MultichainAccountSelectorList.tsx: Migrated Text, TextFieldSearch to new DS. testID prop moved to inputProps.testID in TextFieldSearch - this could break E2E tests that query by this testID.

  3. AccountListCell.tsx: Migrated Checkbox to new DS. Props changed (isCheckedisSelected, onPressonChange). New ACCOUNT_LIST_CELL_CHECKBOX_ICON_TEST_ID added.

  4. ExternalAccountCell.tsx: Migrated AvatarAccount, Avatar, Text to new DS.

  5. MultichainAddressRow.tsx: Migrated Avatar to AvatarNetwork, updated toast handling.

  6. avatarAccountVariant.ts: New utility bridging legacy AvatarAccountType strings to new AvatarAccountVariant enum.

Impact assessment:

  • MultichainAccountSelectorList is used in: main AccountSelector (account switching), confirmations AccountSelector, MultichainAccountConnectMultiSelector (dApp connections), Bridge RecipientSelectorModal, and Notifications settings.
  • AccountCell is used throughout account list flows.
  • MultichainAddressRow is used in AddressList and PrivateKeyList (wallet details/SRP export).

Tags selected:

  • SmokeAccounts: Account selector, account switching, SRP export flows use these components directly.
  • SmokeConfirmations: Confirmations AccountSelector uses MultichainAccountSelectorList - account selection in confirmation flows.
  • SmokeNetworkExpansion: MultichainAccountConnectMultiSelector uses this list for dApp connections (Solana/multi-chain).
  • SmokeNetworkAbstractions: dApp chain permissions and account selection flows.
  • SmokeSwap: Bridge RecipientSelectorModal uses MultichainAccountSelectorList for recipient selection.
  • SmokeWalletPlatform: Multi-SRP architecture, account management, wallet details use MultichainAddressRow.
  • SmokeIdentity: Account sync features use account list components.

The testID change in TextFieldSearch (testIDinputProps.testID) is particularly risky as it could break E2E tests that query the search input by testID in account selector flows.

Performance Test Selection:
The MultichainAccountSelectorList uses FlashList for rendering account lists. The migration to new design system components could affect rendering performance of the account list. The @PerformanceAccountList tag covers account selector and multi-account scenarios which directly exercise these changed components. Other performance tags are not relevant as the changes are limited to account list UI components.

View GitHub Actions results

@sonarqubecloud
Copy link
Copy Markdown

Copy link
Copy Markdown
Contributor

@ccharly ccharly left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM (not tested)

const toastOptions: CopyToastOptions = {
variant: 'Plain',
labelOptions: [{ label: copyParams.toastMessage }],
labelOptions: [{ label: copyParams.toastMessage ?? '' }],
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: Not sure we really need the fallback part here since we check for && copyParams.toastMessage above 🤔

closeButtonOptions: {
variant: ButtonIconVariant.Icon,
iconName: ToastIconName.Close,
variant: 'Icon',
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(I'll keep this unresolved for visibility)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

no-changelog no-changelog Indicates no external facing user changes, therefore no changelog documentation needed size-M team-accounts-framework Accounts team

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants